Imports OMANE.Common.UI
Imports System.Windows.Controls


Public Class ViewModelDashboard
    Inherits UIObject
    Implements IViewModelTabSection



    Sub New()
        Icone = StandardIcons.TRAFFIC
        _EditingGrid.RowDefinitions.Add(New Windows.Controls.RowDefinition())
        _EditingGrid.ColumnDefinitions.Add(New Windows.Controls.ColumnDefinition())
    End Sub
    Sub New(ByVal RowCount As Integer, ByVal ColumnCount As Integer)
        Icone = StandardIcons.TRAFFIC
        Me._RowCount = RowCount
        Me._ColumnCount = ColumnCount
        CreateLayout()
    End Sub

    Public Property Icone As String Implements IViewModelTabSection.Icone

    Public Property ProjectFileName As String

    Public Property ExternalFileName As String

    Private _RowCount As Integer = 1
    Public Property RowCount As Integer
        Get
            Return _RowCount
        End Get
        Set(ByVal value As Integer)
            If value < 1 Then Return
            If value = _RowCount Then Return
            _RowCount = value
            OnPropertyChanged("RowCount")
        End Set
    End Property

    Private _ColumnCount As Integer = 1
    Public Property ColumnCount As Integer
        Get
            Return _ColumnCount
        End Get
        Set(ByVal value As Integer)
            If value < 1 Then Return
            If value = _ColumnCount Then Return
            _ColumnCount = value
            OnPropertyChanged("ColumnCount")
        End Set
    End Property

    Private _Title As String
    Public Property Title As String Implements IViewModelTabSection.Title
        Get
            Return _Title
        End Get
        Set(ByVal value As String)
            _Title = value
            OnPropertyChanged("Title")
        End Set
    End Property

    Private _EditingGrid As New Windows.Controls.Grid
    Public ReadOnly Property EditingGrid As Windows.Controls.Grid
        Get
            Return _EditingGrid
        End Get
    End Property

    Friend _Name As String
    Public ReadOnly Property Name As String
        Get
            Return _Name
        End Get
    End Property



    Public Sub Save(ByVal x As XElement)
        x.SetAttributeValue("RowCount", _RowCount)
        x.SetAttributeValue("ColumnCount", _ColumnCount)
        x.SetAttributeValue("Title", _Title)

        For i = 0 To _EditingGrid.RowDefinitions.Count - 1
            Dim def = _EditingGrid.RowDefinitions(i)
            x.Add( _
                <Row
                    Index=<%= i %>
                    Size=<%= def.Height %>
                    SizeType=<%= def.Height.GridUnitType.ToString() %>
                    SizeValue=<%= def.Height.Value.ToString(Globalization.CultureInfo.InvariantCulture) %>
                    MinSize=<%= def.MinHeight.ToString(Globalization.CultureInfo.InvariantCulture) %>
                    MaxSize=<%= def.MaxHeight.ToString(Globalization.CultureInfo.InvariantCulture) %>
                />)
        Next

        For i = 0 To _EditingGrid.ColumnDefinitions.Count - 1
            Dim def = _EditingGrid.ColumnDefinitions(i)
            x.Add( _
                <Column
                    Index=<%= i %>
                    Size=<%= def.Width %>
                    SizeType=<%= def.Width.GridUnitType.ToString() %>
                    SizeValue=<%= def.Width.Value.ToString(Globalization.CultureInfo.InvariantCulture) %>
                    MinSize=<%= def.MinWidth.ToString(Globalization.CultureInfo.InvariantCulture) %>
                    MaxSize=<%= def.MaxWidth.ToString(Globalization.CultureInfo.InvariantCulture) %>
                />)
        Next

        For Each child In _EditingGrid.Children

            Dim splitter = TryCast(child, GridSplitter)

            If splitter IsNot Nothing Then

                x.Add( _
                    <Splitter
                        Name=<%= splitter.Name %>
                        Row=<%= Grid.GetRow(splitter) %>
                        RowSpan=<%= Grid.GetRowSpan(splitter) %>
                        Column=<%= Grid.GetColumn(splitter) %>
                        ColumnSpan=<%= Grid.GetColumnSpan(splitter) %>
                        IsEnabled=<%= splitter.IsEnabled %>
                        Visibility=<%= splitter.Visibility %>/>)

            End If
        Next

        For Each child In _EditingGrid.Children
            Dim zone = TryCast(child, ViewDashboardZone)

            If zone IsNot Nothing Then
                zone.Save(x)
            End If
        Next

    End Sub

    Public Sub LoadZone(ByVal xelt As System.Xml.Linq.XElement, ByVal iscopy As Boolean)
        Dim zone As ViewDashboardZone = System.Windows.Markup.XamlReader.Load(xelt.FirstNode.CreateReader())
        zone.Name = xelt.@Name
        zone.Title = xelt.@Title
        zone.TitleVisibility = xelt.@TitleVisibility
        zone.LayoutBlocked = xelt.@LayoutBlocked
        zone.ResizingBlocked = xelt.@ResizingBlocked

        '  Dim zonedetailtype = Type.GetType(xelt.@TypeAssemblyQualifiedName, True, True)
        ' MsgBox(If(zonedetailtype Is Nothing, xelt.@TypeAssemblyQualifiedName & "not found", "..."))
        Dim xeltTypeFullName As String = xelt.@TypeFullName
        Dim zonedetailtype = From kvp In ModuleDashboarding._zonetypes
                             Where kvp.Value.FullName = xeltTypeFullName
                             Select kvp.Value
        Dim zonedetail = CType(Activator.CreateInstance(zonedetailtype.FirstOrDefault()), DashboardZone)

        zonedetail.OnDeserializeVisual(System.Windows.Markup.XamlReader.Load(xelt.<ZoneVisual>.FirstOrDefault().FirstNode.CreateReader()))

        SetGridLayout( _
            zone, _
            CInt(xelt.@Row), _
            CInt(xelt.@RowSpan), _
            CInt(xelt.@Column), _
            CInt(xelt.@ColumnSpan))

        zone.DataContext = zonedetail

        _EditingGrid.Children.Add(zone)
    End Sub

    Public Sub Load(ByVal x As XElement)
        Title = x.@Title

        For Each xelt In x.<Row>
            Dim def = _EditingGrid.RowDefinitions(CInt(xelt.@Index))
            def.MinHeight = Double.Parse(xelt.@MinSize, Globalization.CultureInfo.InvariantCulture)
            def.MaxHeight = Double.Parse(xelt.@MaxSize, Globalization.CultureInfo.InvariantCulture)
            def.Height = New Windows.GridLength( _
                Double.Parse(xelt.@SizeValue, Globalization.CultureInfo.InvariantCulture), _
                [Enum].Parse(GetType(Windows.GridUnitType), xelt.@SizeType))
        Next

        For Each xelt In x.<Column>
            Dim def = _EditingGrid.ColumnDefinitions(CInt(xelt.@Index))
            def.MinWidth = Double.Parse(xelt.@MinSize, Globalization.CultureInfo.InvariantCulture)
            def.MaxWidth = Double.Parse(xelt.@MaxSize, Globalization.CultureInfo.InvariantCulture)
            def.Width = New Windows.GridLength( _
                Double.Parse(xelt.@SizeValue, Globalization.CultureInfo.InvariantCulture), _
                [Enum].Parse(GetType(Windows.GridUnitType), xelt.@SizeType))
        Next

        For Each xelt In x.<Splitter>
            Dim splittername = xelt.@Name

            'If String.IsNullOrEmpty(splittername) Then
            Dim qsp = From c In _EditingGrid.Children
                      Where c.GetType() Is GetType(GridSplitter) _
                      And Grid.GetRow(c) = CInt(xelt.@Row) _
                      And Grid.GetRowSpan(c) = CInt(xelt.@Rowspan) _
                      And Grid.GetColumnSpan(c) = CInt(xelt.@ColumnSpan) _
                      And Grid.GetColumn(c) = CInt(xelt.@Column)

            Dim splitter = TryCast(qsp.FirstOrDefault(), GridSplitter)

            If splitter IsNot Nothing Then
                splitter.IsEnabled = CBool(xelt.@IsEnabled)
                splitter.Visibility = [Enum].Parse(GetType(Windows.Visibility), xelt.@Visibility)
            End If
            'Else
            '    Dim splitter As GridSplitter = _EditingGrid..FindName(splittername)
            '    splitter.IsEnabled = CBool(xelt.@IsEnabled)
            '    splitter.Visibility = [Enum].Parse(GetType(Windows.Visibility), xelt.@Visibility)
            'End If
        Next

        For Each xelt In x.<Zone>
            LoadZone(xelt, False)
        Next
    End Sub


    Private Sub CreateLayout()
        If RowCount > 1 Then
            For i = 0 To RowCount - 1
                _EditingGrid.RowDefinitions.Add(New RowDefinition())
                If i < (RowCount - 1) Then
                    _EditingGrid.RowDefinitions.Add(New RowDefinition() With {.Height = Windows.GridLength.Auto})
                End If
            Next
        End If
        If ColumnCount > 1 Then
            For i = 0 To ColumnCount - 1
                _EditingGrid.ColumnDefinitions.Add(New ColumnDefinition())
                If i < (ColumnCount - 1) Then
                    _EditingGrid.ColumnDefinitions.Add(New ColumnDefinition() With {.Width = Windows.GridLength.Auto})
                End If
            Next
        End If

        If RowCount > 1 Then
            For i = 0 To RowCount - 1
                If i < (RowCount - 1) Then
                    Me.AddRowSplitter(i)
                End If
            Next
        End If
        If ColumnCount > 1 Then
            For i = 0 To ColumnCount - 1
                If i < (ColumnCount - 1) Then
                    Me.AddColumnSplitter(i)
                End If
            Next
        End If
    End Sub

    Private Shared zoneinc = 0
    Public Sub AddNewDashboardZone()
        Dim layout = New ViewDashboardZoneLayout()
        zoneinc += 1
        layout.DashboardZoneNameTextBlock.Text = "Zone " & zoneinc
        layout.MaxRowCount = RowCount
        layout.MaxColumnCount = ColumnCount
        layout.RowCountSlider.Maximum = RowCount
        layout.RowSlider.Maximum = RowCount - 1
        layout.ColumnCountSlider.Maximum = ColumnCount
        layout.ColumnSlider.Maximum = ColumnCount - 1
        layout.DashboardZoneTypeCombobox.DisplayMemberPath = "Key"
        layout.DashboardZoneTypeCombobox.ItemsSource = ModuleDashboarding._zonetypes.ToList()

        Dim zname = "zone_" & Guid.NewGuid().ToString().ToLower().Replace("-", "")
        ModuleDashboarding._uiservice.ShowMessage(layout, WindowTitle:="Ajout d'une zone : " & zname & "       ")

        Dim z = New ViewDashboardZone()
        z.Name = zname
        z.Title = layout.DashboardZoneNameTextBlock.Text

        Dim zt = CType(layout.DashboardZoneTypeCombobox.SelectedItem, KeyValuePair(Of String, Type)).Value

        z.DataContext = Activator.CreateInstance(zt)

        SetGridLayoutIgnoreSplitter( _
            z, _
            CInt(layout.RowSlider.Value), _
            CInt(layout.RowCountSlider.Value), _
            CInt(layout.ColumnSlider.Value), _
            CInt(layout.ColumnCountSlider.Value))

        _EditingGrid.Children.Add(z)

        UndoRedoEngine.Instance.ActiveContext = Me
        UndoRedoEngine.Instance.OpenGroup("Ajout d'un(e) " & _
           CType(layout.DashboardZoneTypeCombobox.SelectedItem, KeyValuePair(Of String, Type)).Key)
        UndoRedoEngine.Instance.Push(Sub() Me._EditingGrid.Children.Remove(z), Sub() Me._EditingGrid.Children.Add(z), "Ajout d'un(e) " & _
           CType(layout.DashboardZoneTypeCombobox.SelectedItem, KeyValuePair(Of String, Type)).Key)

        UndoRedoEngine.Instance.CloseGroup()
    End Sub

    Private Sub AddRowSplitter(ByVal index As Integer)
        Dim splitter = New GridSplitter()
        splitter.Name = "_internal_rowsplitter_" & index & "_"
        splitter.Background = Windows.Media.Brushes.Black
        splitter.Height = 2.0
        splitter.HorizontalAlignment = Windows.HorizontalAlignment.Stretch
        splitter.VerticalAlignment = Windows.VerticalAlignment.Stretch
        splitter.ResizeBehavior = GridResizeBehavior.PreviousAndNext
        splitter.ResizeDirection = GridResizeDirection.Rows
        SetGridLayout(splitter, 2 * index + 1, 1, 0, Math.Max(Me._EditingGrid.ColumnDefinitions.Count, 1))

        AddHandler splitter.MouseDoubleClick, Sub() ModuleDashboarding._uiservice.ShowMessage(New ViewDashboardGridDefinition(Me, splitter, index, True), "Modifier la ligne", ShowCloseButton:=False)

        _EditingGrid.Children.Add(splitter)
    End Sub
    Private Sub AddColumnSplitter(ByVal index As Integer)
        Dim splitter = New GridSplitter()
        splitter.Name = "_internal_columnsplitter_" & index & "_"
        splitter.Background = Windows.Media.Brushes.Black
        splitter.Width = 2.0
        splitter.HorizontalAlignment = Windows.HorizontalAlignment.Stretch
        splitter.VerticalAlignment = Windows.VerticalAlignment.Stretch
        splitter.ResizeBehavior = GridResizeBehavior.PreviousAndNext
        splitter.ResizeDirection = GridResizeDirection.Columns
        SetGridLayout(splitter, 0, Math.Max(Me._EditingGrid.RowDefinitions.Count, 1), 2 * index + 1, 1)

        AddHandler splitter.MouseDoubleClick, Sub() ModuleDashboarding._uiservice.ShowMessage(New ViewDashboardGridDefinition(Me, splitter, index, False), "Modifier la colonne", ShowCloseButton:=False)

        _EditingGrid.Children.Add(splitter)
    End Sub

    Private Sub SetGridLayout(ByVal target As Windows.UIElement, ByVal Row As Integer, ByVal RowSpan As Integer, ByVal Column As Integer, ByVal ColumnSpan As Integer)
        Grid.SetRow(target, Row)
        Grid.SetRowSpan(target, RowSpan)
        Grid.SetColumn(target, Column)
        Grid.SetColumnSpan(target, ColumnSpan)
    End Sub
    Private Sub SetGridLayoutIgnoreSplitter(ByVal target As Windows.UIElement, ByVal Row As Integer, ByVal RowSpan As Integer, ByVal Column As Integer, ByVal ColumnSpan As Integer)
        Grid.SetRow(target, 2 * Row)
        Grid.SetRowSpan(target, 2 * RowSpan - 1)
        Grid.SetColumn(target, 2 * Column)
        Grid.SetColumnSpan(target, 2 * ColumnSpan - 1)
    End Sub


    Public Property IsClosable As Boolean Implements IViewModelTabSection.IsClosable
End Class
